package concurrecy;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

class Counter {
    private int count = 0;
    private Random random = new Random();

    public synchronized int increment() {
        int temp = count;
        if(random.nextBoolean())
            Thread.yield();
        return count = temp + 1;
    }

    public int getCount() {
        return count;
    }
}

class Entrance implements Runnable {

    private int count = 0;
    static Counter counter = new Counter();
    private static List<Entrance> entrances = new ArrayList<>();

    private volatile static boolean canceled = false;

    public Entrance() {
        entrances.add(this);
    }

    public static void cancel() {
        canceled = true;
    }

    public static int sumAll() {
        int sum = 0;
        for (Entrance entrance : entrances) {
            System.out.println(entrance);
            sum += entrance.count;
        }
        return sum;
    }

    @Override
    public String toString() {
        return super.toString() + " : " + count;
    }

    @Override
    public void run() {
        while(!canceled) {
            synchronized (this) {
                this.count++;
            }
            counter.increment();
        }
    }
}

public class EntranceDemo {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService service = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            service.execute(new Entrance());
        }
        TimeUnit.SECONDS.sleep(3);
        Entrance.cancel();
        if(!service.awaitTermination(1, TimeUnit.SECONDS))
            System.out.println("task is not terminate");
        service.shutdown();
        System.out.println("Counter -> " + Entrance.counter.getCount());
        System.out.println("Sum all -> " + Entrance.sumAll());
    }
}
